!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},t=(new e.Error).stack;t&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[t]="2e09d8af-ca90-4311-bd71-ce7717d2dc20",e._sentryDebugIdIdentifier="sentry-dbid-2e09d8af-ca90-4311-bd71-ce7717d2dc20")}catch(e){}}();"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7573],{17573:function(e,t,i){i.d(t,{gY:function(){return o},kf:function(){return h},qg:function(){return c}});var n=i(1850),s=n.z.number().int().positive(),a=n.z.array(s),r=n.z.object({pinnedTools:a,theme:n.z.enum(["light","dark","system"])}),d=n.z.object({id:s,url:n.z.string().min(1),icon:n.z.unknown()});n.z.array(d);var o=class{userId;primaryStorage;cacheStorage;options;dualStorageOptions;cacheMetadataKey="_pinned_cache_metadata";defaultPinnedItems;syncTimeoutId=null;pendingSyncData=null;isDestroyed=!1;constructor(e,t,i,n){this.userId=e,this.primaryStorage=t,this.cacheStorage=i,this.dualStorageOptions={cacheExpiry:36e5,backgroundSync:!0,syncDebounceDelay:2e4},this.defaultPinnedItems=[14,20,16],this.options={enableDebug:!1,...n},this.setupBeforeUnloadHandler()}setupBeforeUnloadHandler(){"undefined"!=typeof window&&window.addEventListener("beforeunload",()=>{this.pendingSyncData&&!this.isDestroyed&&this.flushPendingSync()})}validateItemId(e){try{return s.parse(e)}catch(i){let t=`Invalid element ID: ${e}`;throw this.options.enableDebug&&console.error(t,i),Error(t)}}debug(e,t){this.options.enableDebug&&console.log(`[PinnedSidebarClient] ${e}`,t)}getCacheMetadata(){try{if("undefined"==typeof localStorage)return null;let e=localStorage.getItem(this.cacheMetadataKey);if(!e)return null;return JSON.parse(e)}catch(e){return this.debug("Error reading cache metadata",e),null}}setCacheMetadata(){try{if("undefined"==typeof localStorage)return;let e={timestamp:Date.now(),userId:this.userId??0};localStorage.setItem(this.cacheMetadataKey,JSON.stringify(e))}catch(e){this.debug("Error saving cache metadata",e)}}get isCacheExpired(){let e=this.getCacheMetadata();return!e||Date.now()-e.timestamp>this.dualStorageOptions.cacheExpiry||e.userId!==this.userId}async syncCacheWithPrimaryAsync(){try{if(this.pendingSyncData&&(this.debug("Pending sync detected during cache refresh, flushing first"),!await this.flushPendingSync())){this.debug("Failed to flush pending sync, cache refresh aborted");return}let e=await this.primaryStorage.getPinnedItems();this.cacheStorage.clearPinnedItems(),e.forEach(e=>this.cacheStorage.addPinnedItem(e)),this.setCacheMetadata(),this.debug("Cache synchronized with primary storage",{count:e.length})}catch(e){this.debug("Error in background sync",e)}}async syncWithPrimary(e){try{await this.primaryStorage.setPinnedItems(e)?(this.setCacheMetadata(),this.debug("Data synced with primary storage",{count:e.length})):this.debug("Failed to sync with primary storage")}catch(e){this.debug("Error syncing with primary storage",e)}}debouncedSyncWithPrimary(e){this.isDestroyed||(this.syncTimeoutId&&(clearTimeout(this.syncTimeoutId),this.debug("Previous sync timeout cancelled")),this.pendingSyncData=[...e],this.debug("Sync scheduled",{delay:this.dualStorageOptions.syncDebounceDelay,itemCount:e.length}),this.syncTimeoutId=setTimeout(async()=>{if(this.pendingSyncData&&!this.isDestroyed){this.debug("Executing debounced sync");try{await this.syncWithPrimary(this.pendingSyncData),this.debug("Debounced sync completed successfully")}catch(e){this.debug("Debounced sync failed, will retry on next operation",e);return}this.pendingSyncData=null,this.syncTimeoutId=null}},this.dualStorageOptions.syncDebounceDelay))}async flushPendingSync(){if(!this.pendingSyncData)return this.debug("No pending sync data to flush"),!0;this.syncTimeoutId&&(clearTimeout(this.syncTimeoutId),this.syncTimeoutId=null);try{return this.debug("Flushing pending sync data"),await this.syncWithPrimary(this.pendingSyncData),this.pendingSyncData=null,this.debug("Pending sync flushed successfully"),!0}catch(e){return this.debug("Error flushing pending sync",e),!1}}getSyncStatus(){var e;return{hasPendingSync:null!==this.pendingSyncData,pendingItemCount:null==(e=this.pendingSyncData)?void 0:e.length,timeUntilSync:this.syncTimeoutId?this.dualStorageOptions.syncDebounceDelay:void 0}}setSyncDebounceDelay(e){this.dualStorageOptions.syncDebounceDelay=e,this.debug("Sync debounce delay updated",{delay:e})}destroy(){this.isDestroyed=!0,this.syncTimeoutId&&(clearTimeout(this.syncTimeoutId),this.syncTimeoutId=null),this.pendingSyncData&&this.syncWithPrimary(this.pendingSyncData).catch(()=>{this.debug("Failed to sync pending data during destroy")}),this.debug("Client destroyed")}async getPinnedItems(){if(!this.userId)return this.debug("Serving default pinned items because user is not logged in",{count:this.defaultPinnedItems.length,userId:this.userId}),this.defaultPinnedItems;this.isCacheExpired&&await this.syncCacheWithPrimaryAsync();let e=this.cacheStorage.getPinnedItems(),t=e??this.defaultPinnedItems;return this.debug("Serving from cache",{count:t.length,usingDefaults:!(null==e?void 0:e.length)}),t}addPinnedItem(e){if(!this.userId)return!1;try{let t=this.validateItemId(e),i=this.cacheStorage.getPinnedItems(),n=i??this.defaultPinnedItems;if(n.includes(t))return this.debug(`Element ${t} was already pinned`),!1;let s=[...n,t];if(i||this.defaultPinnedItems.forEach(e=>this.cacheStorage.addPinnedItem(e)),this.cacheStorage.addPinnedItem(t))return this.debouncedSyncWithPrimary(s),this.debug(`Element ${t} added`),!0;return!1}catch(e){return this.debug("Error adding pinned element",e),!1}}removePinnedItem(e){if(!this.userId)return!1;try{let t=this.validateItemId(e),i=this.cacheStorage.getPinnedItems(),n=i??this.defaultPinnedItems;if(!n.includes(t))return this.debug(`Element ${t} was not pinned`),!1;if(i||this.defaultPinnedItems.forEach(e=>this.cacheStorage.addPinnedItem(e)),this.cacheStorage.removePinnedItem(t)){let e=n.filter(e=>e!==t);return this.debouncedSyncWithPrimary(e),this.debug(`Element ${t} removed`),!0}return!1}catch(e){return this.debug("Error removing pinned element",e),!1}}clearAll(){if(this.userId)try{this.cacheStorage.clearPinnedItems(),this.setCacheMetadata(),this.debouncedSyncWithPrimary([]),this.debug("All pinned elements cleared")}catch(e){this.debug("Error clearing pinned elements",e)}}async forceCacheRefresh(){try{return await this.syncCacheWithPrimaryAsync(),!0}catch(e){return this.debug("Error during force cache refresh",e),!1}}getCacheInfo(){if(!this.cacheStorage)return{hasCacheStorage:!1,isExpired:!0};let e=this.getCacheMetadata();return{hasCacheStorage:!0,isExpired:this.isCacheExpired,lastUpdated:e?new Date(e.timestamp):void 0,userId:(null==e?void 0:e.userId)??0,itemCount:this.cacheStorage.getPinnedCount()}}},c=class{options;pinnedCache=null;themeCache=null;lastInitialized=null;isInitializing=!1;error=null;cacheDuration=5e3;constructor(e){this.options={timeout:5e3,headers:{"Content-Type":"application/json"},requestOptions:{},...e}}get isCacheValid(){return null!==this.lastInitialized&&this.lastInitialized.getTime()+this.cacheDuration>Date.now()}updatePinnedCache(e){this.pinnedCache=e,this.lastInitialized=new Date}updateThemeCache(e){this.themeCache=e}async initialize(){if(!this.isInitializing){this.isInitializing=!0;try{let e=await this.makeRequest("GET","");if(e.success&&e.data){let t=r.parse(e.data);this.updatePinnedCache(t.pinnedTools),this.updateThemeCache(t.theme)}else this.error=Error("Failed to initialize PinnedApiStorage"),this.updatePinnedCache([])}catch(e){this.error=e,this.updatePinnedCache([])}finally{this.isInitializing=!1}}}async makeRequest(e,t="",i){let n=new AbortController,s=setTimeout(()=>n.abort(),this.options.timeout);try{let a=`${this.options.baseUrl}${t}`,r={method:e,headers:this.options.headers,signal:n.signal,...this.options.requestOptions};i&&["POST","PUT"].includes(e)&&(r.body=JSON.stringify(i));let d=await fetch(a,r);if(clearTimeout(s),!d.ok)throw Error(`HTTP ${d.status}: ${d.statusText}`);let o=await d.json();return{success:!0,data:o}}catch(e){return clearTimeout(s),{success:!1,error:e instanceof Error?e.message:"Unknown error"}}}async getPinnedItems(){if(this.isCacheValid||(await this.initialize(),this.lastInitialized=new Date),this.error)throw this.error;return this.pinnedCache??[]}async setPinnedItems(e){try{let t=a.parse(e);if((await this.makeRequest("PUT","",{pinnedTools:t})).success)return this.updatePinnedCache(t),!0;return!1}catch(e){return console.warn("Error setting pinned items:",e),!1}}async getTheme(){return this.themeCache||await this.initialize(),this.themeCache??"system"}async setTheme(e){try{if((await this.makeRequest("PUT","",{theme:e})).success)return this.updateThemeCache(e),!0;return!1}catch(e){return console.warn("Error setting theme:",e),!1}}},h=class{cookieName;options;constructor(e="pinned_sidebar_items",t){this.cookieName=e,this.options={expires:365,path:"/",secure:"undefined"!=typeof window&&"https:"===window.location.protocol,sameSite:"lax",defaultPinnedItems:[14,20,16],...t}}setCookie(e){if("undefined"==typeof document)return;let{expires:t,domain:i,path:n,secure:s,sameSite:a}=this.options,r=`${this.cookieName}=${encodeURIComponent(e)}`;if(t){let e=new Date;e.setTime(e.getTime()+864e5*t),r+=`; expires=${e.toUTCString()}`}i&&(r+=`; domain=${i}`),n&&(r+=`; path=${n}`),s&&(r+="; secure"),a&&(r+=`; samesite=${a}`),document.cookie=r}getCookie(){if("undefined"==typeof document)return null;let e=`${this.cookieName}=`;for(let t of decodeURIComponent(document.cookie).split(";")){for(;" "===t.charAt(0);)t=t.substring(1);if(0===t.indexOf(e)){let i=t.substring(e.length,t.length);try{let e=JSON.parse(i);return a.parse(e)}catch(e){console.warn("Error parsing pinned items from cookie:",e);break}}}return null}deleteCookie(){if("undefined"==typeof document)return;let{domain:e,path:t}=this.options,i=`${this.cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC`;e&&(i+=`; domain=${e}`),t&&(i+=`; path=${t}`),document.cookie=i}getStoredData(){return this.getCookie()}saveStoredData(e){try{let t=a.parse(e);this.setCookie(JSON.stringify(t))}catch(e){console.error("Error saving pinned items to cookie:",e)}}getPinnedItems(){return this.getStoredData()}addPinnedItem(e){let t=this.getStoredData();if(null==t?void 0:t.includes(e))return!1;let i=[...t??[],e];return this.saveStoredData(i),!0}removePinnedItem(e){let t=this.getStoredData();if(-1===((null==t?void 0:t.indexOf(e))??-1))return!1;let i=(null==t?void 0:t.filter(t=>t!==e))??[];return this.saveStoredData(i),!0}isPinned(e){let t=this.getStoredData();return(null==t?void 0:t.includes(e))??!1}clearPinnedItems(){this.deleteCookie()}getPinnedCount(){var e;return(null==(e=this.getStoredData())?void 0:e.length)??0}updateCookieOptions(e){this.options={...this.options,...e};let t=this.getStoredData();(null==t?void 0:t.length)&&this.saveStoredData(t)}getCookieOptions(){return{...this.options}}}}}]);